home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / r5update.zip / SCALEFON.C < prev    next >
C/C++ Source or Header  |  1991-10-05  |  5KB  |  170 lines

  1. /*
  2.  * scalefonts.c
  3.  *
  4.  * Written by David Flanagan.  Copyright 1991, O'Reilly && Associates.
  5.  * This program is freely distributable without licensing fees and
  6.  * is provided without guarantee or warranty expressed or implied.
  7.  * This program is -not- in the public domain.
  8.  *
  9.  * This program demonstrates the use of scalable fonts in X11R5.
  10.  * Invoke it with a fully specified scalable font name as its
  11.  * only argument.  It will load that font scaled to 7 point,
  12.  * 11 point, 15 point, and 19 point precisely at the resolution
  13.  * of your screen.  It opens a very simple window and draws
  14.  * the font name at each of those point sizes.
  15.  *
  16.  */
  17.  
  18. #include <stdio.h>
  19. #include <X11/Xlib.h>
  20.  
  21. /*
  22.  * This routine returns True only if the passed name is a well-formed
  23.  * XLFD style font name with a pixel size, point size, and average
  24.  * width (fields 7,8, and 12) of "0".
  25.  */ 
  26. Bool IsScalableFont(name) 
  27. char *name; 
  28. {
  29.     int i, field;
  30.     
  31.     if ((name == NULL) || (name[0] != '-')) return False;
  32.     
  33.     for(i = field = 0; name[i] != '\0' && field <= 14; i++) {
  34.     if (name[i] == '-') {
  35.         field++;
  36.         if ((field == 7) || (field == 8) || (field == 12))
  37.         if ((name[i+1] != '0') || (name[i+2] != '-'))
  38.             return False;
  39.     }
  40.     }
  41.     
  42.     if (field != 14) return False;
  43.     else return True;
  44. }
  45.  
  46.  
  47. /*
  48.  * This routine is passed a scalable font name and a point size.
  49.  * It returns an XFontStruct for the given font scaled to the 
  50.  * specified size and the exact resolution of the screen.
  51.  * The font name is assumed to be a well-formed XLFD name,
  52.  * and to have pixel size, point size, and average width fields
  53.  * of "0" and implementation dependent x-resolution and y- 
  54.  * resolution fields.  Size is specified in tenths of points.
  55.  * Returns NULL if the name is malformed or no such font exists.
  56.  */
  57. XFontStruct *LoadQueryScalableFont(dpy, screen, name, size)
  58. Display *dpy;
  59. int screen;
  60. char *name;
  61. int size;
  62. {
  63.     int i,j, field;
  64.     char newname[500];        /* big enough for a long font name */
  65.     int res_x, res_y;         /* resolution values for this screen */
  66.     
  67.     /* catch obvious errors */
  68.     if ((name == NULL) || (name[0] != '-')) return NULL;
  69.     
  70.     /* calculate our screen resolution in dots per inch. 25.4mm = 1 inch */
  71.     res_x = DisplayWidth(dpy, screen)/(DisplayWidthMM(dpy, screen)/25.4);
  72.     res_y = DisplayHeight(dpy, screen)/(DisplayHeightMM(dpy, screen)/25.4);
  73.     
  74.     /* copy the font name, changing the scalable fields as we do so */
  75.     for(i = j = field = 0; name[i] != '\0' && field <= 14; i++) {
  76.     newname[j++] = name[i];
  77.     if (name[i] == '-') {
  78.         field++;
  79.         switch(field) {
  80.         case 7:  /* pixel size */
  81.         case 12: /* average width */
  82.         /* change from "-0-" to "-*-" */
  83.         newname[j] = '*'; 
  84.         j++;
  85.         if (name[i+1] != '\0') i++;
  86.         break;
  87.         case 8:  /* point size */
  88.         /* change from "-0-" to "-<size>-" */
  89.         (void)sprintf(&newname[j], "%d", size);
  90.         while (newname[j] != '\0') j++;
  91.         if (name[i+1] != '\0') i++;
  92.         break;
  93.         case 9:  /* x resolution */
  94.         case 10: /* y resolution */
  95.         /* change from an unspecified resolution to res_x or res_y */
  96.         (void)sprintf(&newname[j], "%d", (field == 9) ? res_x : res_y);
  97.         while(newname[j] != '\0') j++;
  98.         while((name[i+1] != '-') && (name[i+1] != '\0')) i++;
  99.         break;
  100.         }
  101.     }
  102.     }
  103.     newname[j] = '\0';
  104.     
  105.     /* if there aren't 14 hyphens, it isn't a well formed name */
  106.     if (field != 14) return NULL;
  107.     
  108.     return XLoadQueryFont(dpy, newname);
  109. }
  110.  
  111. int sizes[] = {70,110,150,190};
  112.  
  113. main(argc, argv)
  114. int argc;
  115. char *argv[];
  116. {
  117.     Display *d;
  118.     int screen;
  119.     Window w;
  120.     GC gc;
  121.     XGCValues gcv;
  122.     XFontStruct *f[4];
  123.     XEvent event;
  124.     int i;
  125.     
  126.     if (argc != 2) {
  127.     (void) fprintf(stderr, "Usage: %s fontname\n", argv[0]);
  128.     exit(1);
  129.     }
  130.  
  131.     if (!IsScalableFont(argv[1])) {
  132.     (void) fprintf(stderr,
  133.                "%s: not a fully specified scalable font name.\n",
  134.                argv[0]);
  135.     exit(1);
  136.     }
  137.     
  138.     if ((d = XOpenDisplay(NULL)) == NULL) {
  139.     (void) fprintf(stderr, "%s: can't open display.\n", argv[0]);
  140.     exit(1);
  141.     }
  142.     
  143.     screen = DefaultScreen(d);
  144.     w = XCreateSimpleWindow(d, RootWindow(d, screen), 0, 0, 600, 250,
  145.                 3, WhitePixel(d,screen),BlackPixel(d,screen));
  146.     
  147.     for(i=0; i < 4; i++)
  148.     f[i] = LoadQueryScalableFont(d, screen, argv[1], sizes[i]);
  149.     
  150.     gc = XCreateGC(d,w,0,&gcv);
  151.     XSetForeground(d,gc,WhitePixel(d,screen));
  152.  
  153.     XSelectInput(d, w, ExposureMask);
  154.     XMapWindow(d,w);
  155.  
  156.     while(1) {
  157.     XNextEvent(d, &event);
  158.     switch(event.type) {
  159.     case Expose:
  160.         if (event.xexpose.count == 0) {
  161.         for(i=0; i<4; i++) {
  162.             XSetFont(d,gc,f[i]->fid);
  163.             XDrawString(d,w,gc,10,10+30*i,argv[1], strlen(argv[1]));
  164.         }
  165.         }
  166.         break;
  167.     }
  168.     }
  169. }
  170.